"use strict";

/**
 * ┌─>│           timers          │
 * │  └─────────────┬─────────────┘
 * │  │     pending callbacks     │
 * │  └─────────────┬─────────────┘
 * │  │       idle, prepare       │
 * │  └─────────────┬─────────────┘      │   incoming:   │
 * │  │           poll            │<─────┤  connections, │
 * │  └─────────────┬─────────────┘      │   data, etc.  │
 * │  │           check           │
 * │  └─────────────┬─────────────┘
 * └──┤      close callbacks      │
 */

/**
 * - __timers__: this phase executes callbacks scheduled by `setTimeout()` and `setInterval()`.
 * - __pending__ callbacks: executes `I/O callbacks` deferred to the next loop iteration.
 * - __idle__, prepare: only used internally.
 * - __poll__: retrieve new I/O events; execute I/O related callbacks (almost all with the exception of close callbacks, the ones scheduled by timers, and setImmediate()); node will block here when appropriate.
 * - __check__: `setImmediate()` callbacks are invoked here.
 * - __close__ callbacks: some close callbacks, e.g. `socket.on('close', ...)`.
 */
const eventLoop = {};

const fs = require("node:fs");
const path = require("node:path");

/**
 * @param {(err: NodeJS.ErrnoException | null, data: NonSharedBuffer) => void} callback
 */
function someAsyncOperation(callback) {
  // Assume this takes 95ms to complete
  fs.readFile(path.resolve(__filename), null, callback);
}

const timeoutScheduled = Date.now();

setTimeout(() => {
  const delay = Date.now() - timeoutScheduled;

  console.log(`${delay}ms have passed since I was scheduled`);
}, 100);

// do someAsyncOperation which takes 95 ms to complete
someAsyncOperation(() => {
  const startCallback = Date.now();

  // do something that will take 10ms...
  while (Date.now() - startCallback < 10) {
    // do nothing
  }
});
